<!doctype html>
  <html>
    <head>
      <link rel="stylesheet" href="/node_modules/xterm/css/xterm.css" />
      <script src="/node_modules/xterm/lib/xterm.js"></script>
      <script src="/node_modules/xterm-addon-fit/lib/xterm-addon-fit.js"></script>
    </head>
    <body>
      <div id="terminal"></div>
      <script>
        let sock_obj = {};
        var glo = {};
        // 初始化websocket
        sock_obj.initSocket = function () {
            // console.log(url)
            this.socket = new WebSocket('ws://127.0.0.1:2345')
            sock_obj.openSocket();
            sock_obj.closeSocket();
            sock_obj.errorSocket();
            sock_obj.messageSocket();
            glo.socket = this
        };
        // 打开连接
        sock_obj.openSocket = function () {
          this.socket.onopen = () => {
            // 初始化term
            term_obj.initTerm();
            this.sendData(1)
          }
        };
        // 关闭连接
        sock_obj.closeSocket = function () {
          this.socket.onclose = () => {

            console.log('websoket连接关闭');

          }
        };
        // 连接错误
        sock_obj.errorSocket = function () {
          this.socket.onerror = () => {
            $.msg.error('websoket连接失败，请刷新！');
            console.log('websoket连接失败，请刷新！');
          }
        };
        // 消息回调
        sock_obj.messageSocket = function () {
          this.socket.onmessage = (res) => {
            // console.log(res)
            if (res.data.length !== 0) {
              let data = res.data
              let result = data
              let color = '\x1b[37m'
              // console.log(typeof data)
              if (res.data.substr(0,1).indexOf('{') !== -1) {
                data = JSON.parse(data)
                glo.sshPrompt = data.prompt
                if (data.status === 'status') {
                  color = '\x1b[94m'    // 蓝色
                } else if (data.status === 'error') {
                  color = '\x1b[91m'    // 红色
                } else if (data.status === 'good') {
                  color = '\x1b[92m'    // 绿色
                } else if (data.status === 'warning') {
                  color = '\x1b[93m'    // 黄色
                } else {
                  color = '\x1b[37m'    // 白色
                }
                result = data.data
                if(result.length > 0){
                  for (let i = 0; i < result.length; i++) {
                    glo.that.term.write('\r\n'+ color + result[i])
                  }
                }
                //glo.that.term.write('\r\n'+ color + result)
                if (data.busy) {
                  return
                }
              } else {
                glo.that.term.write('\r\n' + color + result)
              }
              glo.that.term.prompt()
              // setTimeout(, 2000)
            }
          }
        };

        // 发送消息
        sock_obj.sendData = function (status) {
          if(status == 1){
            glo.that.term.write('connecting...')
            this.socket.send('');
          }else{
            let command = glo.that.command
            this.socket.send(command);
          }
        }

        let term_obj = {}
        // 初始化终端
        term_obj.initTerm = function () {
              let that = this
              let termContainer = document.getElementById('terminal')
              that.command = '';
              localStorage.setItem('commands', '')
              that.cols = termContainer.offsetWidth / 9
              that.rows = termContainer.offsetHeight / 9
              let term = new Terminal({
                cursorBlink: true,
                rendererType: "canvas", //渲染类型
                rows: 40, //行数
                disableStdin: false, //是否应禁用输入
                cols: parseInt(that.cols),
                theme: {
                  cursorStyle: 'underline', //光标样式
                  cursorBlink: true, //光标闪烁
                  // foreground: "#7e9192", //字体
                  fontFamily: 'DejaVu',
                  lineHeight: 16
                }
              })
              let fitAddon = new FitAddon.FitAddon();
              term.loadAddon(fitAddon)
              term.open(termContainer)
              term.prompt = function () {
                let color = '\x1b[33m'
                term.write('\r\n' + color + glo.sshPrompt + '$\x1b[0m ');
              }
              fitAddon.fit()
              // 内容全屏显示-窗口大小发生改变时
              function resizeScreen() {
                // console.log("size", size);
                try {
                  fitAddon.fit();
                } catch (e) {
                  console.log("e", e.message);
                }
              }
              window.addEventListener("resize", resizeScreen)
              term.focus()  // 光标聚焦
              // 添加事件监听器，支持输入方法
              term.onData( function (key) {
                if (key.charCodeAt(0) == 13) { // 回车
                  if(that.command === 'clear') {
                    term.clear()
                  }
                  if (that.command.length === 0) {
                    term.prompt()
                  } else {
                    // 保存命令
                    let commands = localStorage.getItem('commands') ? JSON.parse(localStorage.getItem('commands')) : []
                    commands.push(that.command)
                    localStorage.setItem('commands', JSON.stringify(commands))
                    localStorage.setItem('index', commands.length)
                    sock_obj.sendData(0)
                  }
                  that.command = ''
                } else if (key === '\u001b[A') {   // 向上方向
                  let commands = localStorage.getItem('commands') ? JSON.parse(localStorage.getItem('commands')) : []
                  let index = localStorage.getItem('index') ? localStorage.getItem('index') : commands.length
                  index = parseInt(index)
                  if (commands.length && index < commands.length + 1 && index > 0) {
                    // 删除现有命令
                    for (let i = 0; i < that.command.length; i++) {
                      if (term._core.buffer.x > (glo.sshPrompt.length + 2)) {
                        term.write('\b \b')
                      }
                    }
                    that.command = commands[index - 1]
                    term.write(that.command)
                    localStorage.setItem('index', index - 1)
                  }
                } else if (key  === '\u001b[B') {   // 向下方向
                  let commands = localStorage.getItem('commands') ? JSON.parse(localStorage.getItem('commands')) : []
                  let index = localStorage.getItem('index') ? localStorage.getItem('index') : commands.length
                  index = parseInt(index)
                  if (commands.length && index < commands.length - 1 && index > -1) {
                    // 删除现有命令
                    for (let i = 0; i < that.command.length; i++) {
                      if (term._core.buffer.x > (glo.sshPrompt.length + 2)) {
                        term.write('\b \b')
                      }
                    }
                    that.command = commands[index + 1]
                    term.write(that.command)
                    localStorage.setItem('index', index + 1)
                  }
                } else if (key === '\u0003') {   // Ctrl+C
                  term.write("^C ");
                  term.prompt();
                } else if (key.charCodeAt(0) === 127) {   // 删除
                    if (term._core.buffer.x > glo.sshPrompt.length + 2) {
                      term.write('\b \b');
                    }
                } else{
                  that.command += key
                  term.write(key)
                }
              })
              that.term = term
              glo.that = that
            };

            // 初始化websocket
            sock_obj.initSocket();
      </script>
    </body>
  </html>